package com.sy.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.sy.entity.User;
import com.sy.service.UserService;
import com.sy.utils.CommonUtils;
import com.sy.utils.RandomUtils;
import com.sy.utils.RedisOperations;
import com.sy.utils.SMSUtils;
import com.sy.vo.CustomerInfo;
import com.sy.vo.LoginVo;
import com.sy.vo.RegistVo;
import com.sy.vo.UpdateUserVo;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Objects;

import static com.sy.constant.BusinessConstant.*;
import static com.sy.constant.RegConstant.PHONE_REGEX;
import static com.sy.constant.RegConstant.STRONG_PWD_REGEX;

@Service
public class UserServiceImpl extends BaseServiceImpl implements UserService {

    @Autowired
    private RedisOperations redisOperations;

    @Override
    public void sendValidateCode(String phone) {
        if (StringUtils.isBlank(phone)) {
            buildError(HttpStatus.NOT_FOUND,"手机号不能为空");
        }
        if (!phone.matches(PHONE_REGEX)) {
            buildError(HttpStatus.BAD_REQUEST, "手机号格式不合法");
        }
        //要发送的验证码
        String validateCode = RandomUtils.getRandomString(4);

        //调用短信平台发送短信验证码
        JSONObject resultJson = SMSUtils.sendValidateCode(phone, validateCode);
        if (resultJson.getIntValue("result") != SMS_SUCCESS_CODE) {
            buildError(HttpStatus.BAD_REQUEST, "短信发送失败，请重试！");
        }
        //如果短信发送成功，则在Redis中保存当前手机号收到的验证码，用于后面注册逻辑中的比对操作
        else {
            String key = REDIS_VALIDATE_CODE_KEY_PREFIX + phone;
            redisOperations.set(key, validateCode);
            redisOperations.expire(key, VALIDATE_CODE_EXPIRE_SECONDS);
        }

    }

    @Override
    public void regist(RegistVo registVo) {
        String userName = registVo.getUserName();
        String userPwd = registVo.getUserPwd();
        String userPwdConfirm = registVo.getUserPwdConfirm();
        String phone = registVo.getPhone();
        String validateCode = registVo.getValidateCode();
        String type = registVo.getType();
        // 用户名不能为空
        if (StringUtils.isBlank(userName)) {
            buildError(HttpStatus.NOT_FOUND,"用户名不能为空");
        }
        // 用户名不能重复
        if (!Objects.isNull(userMapper.getUserByUserName(userName))) {
            buildError(HttpStatus.BAD_REQUEST,"用户名已存在");
        }

        // 密码不能为空
        if (StringUtils.isBlank(userPwd)) {
            buildError(HttpStatus.NOT_FOUND,"密码不能为空");
        }
        // 密码必须是强密码类型
        if (!userPwd.matches(STRONG_PWD_REGEX)) {
            buildError(HttpStatus.BAD_REQUEST,"密码必须是强密码类型");
        }
        // 两次输入的密码必须一致
        if (!StringUtils.equals(userPwd, userPwdConfirm)) {
            buildError(HttpStatus.BAD_REQUEST,"两次密码输入必须一致");
        }
        // 手机号不能为空
        if (StringUtils.isBlank(phone)) {
            buildError(HttpStatus.NOT_FOUND,"手机号不能为空");
        }
        // 手机号的格式必须合法
        if (!phone.matches(PHONE_REGEX)) {
            buildError(HttpStatus.BAD_REQUEST,"手机号格式不合法");
        }
        // 相同的手机号不能重复注册
        if (!Objects.isNull(userMapper.getUserByPhone(phone))) {
            buildError(HttpStatus.BAD_REQUEST,"手机号已被注册");
        }
        //身份类型不能为空
        if (StringUtils.isBlank(type)) {
            buildError(HttpStatus.NOT_FOUND, "身份类型不能为空");
        }
        //没有匹配的身份类型
        if (!StringUtils.equals(STUDENT_NAME, type) && !StringUtils.equals(COACH_NAME, type)) {
            buildError(HttpStatus.BAD_REQUEST, "身份类型不合法");
        }
        // 验证码通过短信发送且需要通过验证（不区分大小写）
        //(1)先从Redis中获取当前手机号对应的验证码
        String correctValidateCode = redisOperations.get(REDIS_VALIDATE_CODE_KEY_PREFIX + phone);
        //(2)如果Redis中不存在验证码
        if (StringUtils.isBlank(correctValidateCode)) {
            buildError(HttpStatus.NOT_FOUND,"验证码已过期，请重新获取！");
        }
        //(3)如果验证码存在
        else {
            if (!StringUtils.equalsIgnoreCase(correctValidateCode, validateCode)) {
                buildError(HttpStatus.BAD_REQUEST,"验证码填写错误！");
            }
        }

        //如果验证都通过，将用户信息存入数据库
        User user = new User();
        user.setUserName(userName);
        user.setPwd(DigestUtils.md5Hex(userPwd));
        user.setPhone(phone);
        user.setType(type);
        userMapper.addUser(user);
    }

    @Override
    public User login(LoginVo loginVo) {
        if (StringUtils.isBlank(loginVo.getUserName())) {
            buildError(HttpStatus.NOT_FOUND,"用户名不能为空");
        }
        if (StringUtils.isBlank(loginVo.getUserPwd())) {
            buildError(HttpStatus.NOT_FOUND,"密码不能为空");
        }
        if (StringUtils.isBlank(loginVo.getType())) {
            buildError(HttpStatus.NOT_FOUND, "身份类型不能为空");
        }
        User user = userMapper.getUserByUserName(loginVo.getUserName());
        if (Objects.isNull(user)) {
            buildError(HttpStatus.NOT_FOUND,"用户不存在");
        }
        if (!StringUtils.equals(user.getPwd(), DigestUtils.md5Hex(loginVo.getUserPwd()))) {
            buildError(HttpStatus.BAD_REQUEST,"密码错误");
        }
        if (!StringUtils.equals(user.getType(), loginVo.getType())) {
            buildError(HttpStatus.BAD_REQUEST, "身份类型不匹配");
        }
        user.setPwd(null);

        return user;
    }

    @Override
    public void updateUserInfoByConditions(UpdateUserVo updateUserVo, String token) {
        if (StringUtils.isNotBlank(token) && !Objects.isNull(updateUserVo.getUserId())) {
            if (StringUtils.isBlank(updateUserVo.getUserName())) {
                buildError(HttpStatus.NOT_FOUND,"用户名不能为空");
            }
            if (StringUtils.isBlank(updateUserVo.getPhone())) {
                buildError(HttpStatus.NOT_FOUND,"手机号不能为空");
            }
            //判断是否更新用户信息
            boolean isUpdate = userMapper.updateUserInfoByConditions(updateUserVo.getUserName(), updateUserVo.getPhone(), updateUserVo.getUserId());
            //如果更新了就同步更新redis中的用户信息
            if (isUpdate) {
                String redisUserKey = REDIS_USER_KEY_PREFIX + token;
                User user = new User();
                user.setUserName(updateUserVo.getUserName());
                user.setPhone(updateUserVo.getPhone());
                user.setId(updateUserVo.getUserId());
                Map<String, String> userMap = CommonUtils.bean2Map(user);
                userMap.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
                redisOperations.hmset(redisUserKey, userMap);
            }
        } else {
            buildError(HttpStatus.NOT_FOUND, "用户未登录");
        }
    }

    @Override
    public void submitCustomerInfo(CustomerInfo customerInfo) {

        // 验证码通过短信发送且需要通过验证（不区分大小写）
        //(1)先从Redis中获取当前手机号对应的验证码
        String correctValidateCode = redisOperations.get(REDIS_VALIDATE_CODE_KEY_PREFIX + customerInfo.getPhone());
        System.out.println(correctValidateCode);
        //(2)如果Redis中不存在验证码
        if (StringUtils.isBlank(correctValidateCode)) {
            buildError(HttpStatus.NOT_FOUND,"验证码已过期，请重新获取！");
        }
        //(3)如果验证码存在
        else {
            if (!StringUtils.equalsIgnoreCase(correctValidateCode,customerInfo.getCode())) {
                buildError(HttpStatus.BAD_REQUEST,"验证码填写错误！");
            }
        }

//        //调用短信平台发送短信验证码
//        JSONObject resultJson = SMSCustomerUtils.sendValidateCode(customerInfo.getPhone(),customerInfo.getOnPhone(),customerInfo.getUserName());
//        if (resultJson.getIntValue("result") != SMS_SUCCESS_CODE) {
//            buildError(HttpStatus.BAD_REQUEST, "短信发送失败，请重试！");
//        }




    }
}
